<template>
  <view>
    <view class="header">
      <search v-if="searchIf" ref="searchRef" @confirm="confirmSearch" />
      <view class="title">
        <scroll-view scroll-x style="width: 100%;white-space: nowrap;" :scroll-left="scrollLeft">
          <view v-for="(item,index) in tree_stack" class="inline-item" :key="index">
            <view class="inline-item" v-if="index==0" @click="backTree(item,-1)">
              <text :class="[(isActive(index)&&!isre)?'none':'active']">全部</text>
            </view>
            <view v-if="index==0&&isre" @click="backTree(item,-2)"
              :class="[(index==tree_stack.length-1&&isre)?'none':'active','inline-item']">
              <i class="iconfont icon-z043 iconclass" />
              搜索结果
            </view>
            <view class="inline-item" @click="backTree(item,index)" v-if="index!=0">
              <i class="iconfont icon-z043 iconclass" />
              <text :class="isActive(index)?'none inline-ite':'active'">
                {{item[props.options.label]}}
              </text>
            </view>
          </view>
        </scroll-view>
      </view>
    </view>
    <view>
      <view class="container-list">
        <view class="common" v-for="(item, index) in tree" @click="handleClick(item,index)" :key="index">
          <label class="content">
            <view class="list-item" v-show="isCheck">
              <!-- 多选 -->
              <view class="checkbox" v-if="props.options.multiple" @click.stop="handleClick(item,-1)">
                <span v-if="isSelect(item)">
                  <i v-if="item.bx&&newCheckList.length!=0" class="iconfont icon-banxuanzhongshousuo1-shi icons" />
                  <i v-else class="iconfont icon-xuanzhong txt icon-selected" />
                </span>
                <i v-else-if="item.qx" class="iconfont icon-xuanzhong txt icon-selected" />
                <i v-else-if="item.bx" class="iconfont icon-banxuanzhongshousuo1-shi icons" />
                <i style="color: #b8b8b8;" v-else class="iconfont icon-weixuanzhong txt" />
              </view>
              <!-- 单选 -->
              <view class="checkbox" v-else-if="(props.options.nodes?item.user?true:false:true)"
                @click.stop="handleClick(item,-1)">
                <i v-if="radioSelect(item)" class="txt iconfont icon-selected" />
                <i style="color: #b8b8b8;" v-else class="txt iconfont icon-weixuanzhong1" />
              </view>
            </view>
            <view class="lable-text">
              <image v-if="!item.user" class="lable-img" src="../../../static/images/icon_department.png" />
              {{item[props.options.label]}}
            </view>
            <view class="right"><i v-if="!item.user&&item.children.length>0" class="iconfont icon-z043 iconclass"></i>
            </view>
          </label>
        </view>
      </view>
    </view>
    <view class="btn box_sizing" v-if="isCheck">
      <button class="sureBtn" type="primary" @click="backConfirm">确认</button>
    </view>
  </view>
</template>

<script setup>
  import search from './search/index.vue'
  import {
    ref,
    reactive,
    defineProps,
    computed,
    nextTick,
    defineEmits
  } from 'vue'
  const props = defineProps({
    treeNone: {
      type: Array,
      default: () => {
        return []
      }
    },
    checkList: {
      type: Array,
      default: () => {
        return []
      }
    },
    keyValue: {
      type: String,
      default: 'id'
    },
    searchIf: {
      type: Boolean,
      default: true
    },
    //是否选择模式
    isCheck: true,
    checkList: {
      type: Array,
      default: () => []
    },
    parentList: {
      type: Array,
      default: () => []
    },
    options: {
      type: Object,
      default: () => {
        return {
          label: 'name',
          children: 'children',
          multiple: false,
          checkStrictly: false //不关联
        }
      }
    }
  })

  const catchTreeNone = JSON.parse(JSON.stringify(props.treeNone)),
    tree = ref(props.treeNone),
    newCheckList = ref(props.checkList),
    tree_stack = ref([1]),
    nodePathArray = ref([]),
    searchResult = ref([]),
    scrollLeft = ref(999),
    oldNum = ref(0),
    newNum = ref(0),
    isre = ref(false),
    searchRef = ref(null);
  const emit = defineEmits(['sendValue'])
  // 初始化
  const initComponent = () => {
    if (newCheckList.value.length !== 0) {
      if (props.options.multiple) {
        if (props.options.checkStrictly) {
          checkAllChoose();
        }
      } else {
        console.log(catchTreeNone)
        getNodeRoute(catchTreeNone, newCheckList.value[0][props.keyValue])
        let arr = nodePathArray.value.reverse()
        if (arr.length == 0) return
        tree_stack.value = tree_stack.value.concat(arr);
        tree.value = tree_stack.value[tree_stack.value.length - 1].children;
      }
    }
    console.log(props.options)
  }
  initComponent()
  // (tree为目标树，targetId为目标节点id)
  function getNodeRoute(tree, targetId) {
    for (let index = 0; index < tree.length; index++) {
      if (tree[index].children) {
        let endRecursiveLoop = getNodeRoute(tree[index].children, targetId)
        if (endRecursiveLoop) {
          nodePathArray.value.push(tree[index])
          return true
        }
      }
      if (tree[index][props.keyValue] === targetId) {
        return true
      }
    }
  }

  const radioSelect = computed(() => {
    return (item) => {
      const list = newCheckList.value
      return list.length > 0 && item[props.keyValue] == list[0][props.keyValue]
    }
  })
  const isActive = computed(() => {
    return (index) => {
      return index === tree_stack.value.length - 1
    }
  })
  const isSelect = computed(() => {
    return (item) => {
      const checkList = newCheckList.value
      if (checkList.length == 0) {
        props.options.checkStrictly ? (item.bx = 0, item.qx = 0) : ''
        return false
      }
      const i = checkList.findIndex(e => {
        return item[props.keyValue] == e[props.keyValue]
      }) > -1
      return i && !item.qx
    }
  })
  //到下一级
  function toChildren(item) {
    if (item.user) return
    uni.showLoading({
      title: '加载中'
    })
    let children = props.options.children;
    if (!item.user && item[children].length > 0 && !(tree_stack.value[0][props.keyValue] == item[props.keyValue])) {
      tree.value = item[children];
      tree_stack.value.push(item);
    }
    nextTick(() => {
      uni.hideLoading()
      scrollLeft.value += 200;
    })
    if (props.options.checkStrictly) checkAllChoose();
  }

  function computAllNumber(arr) {
    for (let j = 0; j < arr.length; j++) {
      var e = arr[j];
      checkSum(e[props.keyValue])
      if (e.user) {
        newNum.value++;
      } else {
        computAllNumber(e.children)
      }
    }
  }

  function checkSum(id) {
    for (let i = 0; i < newCheckList.value.length; i++) {
      if (id == newCheckList.value[i][props.keyValue]) {
        oldNum.value++;
        break
      }
    }
  }

  function checkAllChoose() {
    let o = false,
      t = true;
    tree.value.forEach((e, i) => {
      if (!e.user) {
        e.qx = o;
        e.bx = o;
        computAllNumber(e.children);
        if (newNum.value != 0 && oldNum.value != 0) {
          if (newNum.value == oldNum.value) {
            e.qx = t;
            e.bx = o;
          } else {
            e.qx = o;
            e.bx = t;
          }
        }
        if (newNum.value != 0 && oldNum.value == 0) {
          tree.value[i].bx = o
          tree.value[i].qx = o
        }
        newNum.value = 0
        oldNum.value = 0
      }
    })
  }

  //单选 事件
  function checkbox(item, index) {
    console.log('checkBox', item + ' ' + props.isCheck)
    const path = getPath()
    newCheckList.value = [{
      ...item,
      path
    }]
    //非选择状态
    if (!props.isCheck) {
      backConfirm()
    }

  }
  // 获取路径
  function getPath() {
    const path = [...tree_stack.value].map(e => {
      const item = Object.assign({}, e)
      delete item[props.options.children]
      return item
    })
    return path.slice(1, path.length) || []
  }
  // 取消下一级的选中
  function getIdBydelete(arr) {
    arr.forEach(e => {
      if (e.user) {
        for (var i = 0; i < newCheckList.value.length; i++) {
          if (e[props.keyValue] == newCheckList.value[i][props.keyValue]) {
            newCheckList.value.splice(i, 1)
            break;
          }
        }
      } else {
        getIdBydelete(e.children)
      }
    })
  }

  function checkboxChange(item, index, bx, qx) {
    console.log('checkboxChange')
    const options = props.options
    if (!options.multiple) return;
    let findIdex = newCheckList.value.findIndex(e => item[props.keyValue] == e[props.keyValue]);
    const path = getPath();
    if (findIdex > -1) { //反选
      if (options.checkStrictly) { //关联子级
        if (item.user) { //用户
          newCheckList.value.splice(findIdex, 1)
        } else { //非用户，取消所有下一级
          getIdBydelete(item.children)
        }
      } else {
        newCheckList.value.splice(findIdex, 1)
      }
    } else { //选中
      if (!item.user && options.checkStrictly) { //选中下一级
        if (qx || bx) { //取消下级
          getIdBydelete(item.children);
          item.qx = 0;
          item.bx = 0;
        } else {
          item.qx = 1;
          item.bx = 0;
          const {
            id,
            name,
            user
          } = item
          const newObj = {
            id,
            name,
            user
          }
          const pathList = tree_stack.value.length === 1 ? [newObj, ...path] : [...path, newObj]
          chooseChild(item.children, pathList);
        }
        return
      }
      newCheckList.value.push({
        ...item,
        path
      });
    }
  }
  // 关联下一级,选中
  function chooseChild(arr, path) {
    console.log('chooseChild')
    const oldPath = [...path]
    for (var i = 0, len = arr.length; i < len; i++) {
      let item = arr[i];
      if (item.user) {
        newCheckList.value.push({
          ...item,
          path: oldPath
        })
      } else {
        const newItem = {
          ...item
        }
        delete newItem[props.options.children]
        const newPath = [...oldPath, newItem]
        chooseChild(item.children, newPath)
      }
    }
  }
  //搜索
  function confirmSearch(val) {
    searchResult.value = []
    searchTree(catchTreeNone, val)
    isre.value = true
    tree_stack.value.splice(1, 1000)
    uni.showLoading({
      title: '正在查找'
    })
    setTimeout(() => {
      tree.value = searchResult.value
      uni.hideLoading()
    }, 300)
  }

  function searchTree(data, keyword) {
    let children = props.options.children;
    let label = props.options.label;
    for (var i = 0, len = data.length; i < len; i++) {
      if (data[i][label].indexOf(keyword) >= 0) {
        searchResult.value.push(data[i])
      }
      if (!data[i].user && data[i][children].length > 0) {
        searchTree(data[i][children], keyword)
      }
    }
  }


  //返回其它层
  function backTree(item, index) {
    let max = 300;
    if (index === -1) {
      tree.value = catchTreeNone
      tree_stack.value.splice(1, max)
      console.log(tree.value)
      isre.value = false
      // searchRef.value.clears()
    } else if (index === -2) { //搜索
      tree.value = searchResult.value
      tree_stack.value.splice(1, max)
    } else {
      if (tree_stack.value.length - index > 2) {
        tree_stack.value.splice(index + 1, max)
      } else if (index !== tree_stack.value.length - 1) {
        tree_stack.value.splice(tree_stack.value.length - 1, 1)
      }
      tree.value = item[props.options.children]
    }
    if (props.options.checkStrictly) checkAllChoose();
  }
  //选中事件
  function backConfirm() {
    emit('sendValue', newCheckList.value, props.isCheck)
  }

  //点击事件
  const handleClick = (item, index) => {
    let children = item[props.options.children]
    if (index > -1 && children && children.length > 0) { //到下一级
      toChildren(item)
    } else if (props.options.multiple) { //多选
      checkboxChange(item, index, item.bx, item.qx)
    } else { //单选
      checkbox(item, index)
    }
  }
</script>
<style lang="scss" scoped>
  @import './css/style.scss';
  @import url("./css/icon.css");
</style>
